package com.py.credit.service.impl;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.py.credit.dao.CreditMapDao;
import com.py.credit.service.CreditMapService;
import com.py.credit.utils.LonAndLatUtil;
import com.py.credit.utils.SQLBuilder;
import com.py.credit.utils.ThreadMapCallable;
import com.py.framework.core.common.Page;

@Service
public class CreditMapServiceImpl implements CreditMapService {

	@Autowired
	private CreditMapDao creditMapDao;

	public static void main(String args[]) throws ClientProtocolException, IOException {
		String address = "郑州市郑东新区商务内环路10号5层506号";
		System.out.println(address);
		List<NameValuePair> list = new ArrayList<NameValuePair>();
		String qt=URLEncoder.encode("\"","utf-8");
		String le=URLEncoder.encode("{","utf-8");
		String ri=URLEncoder.encode("}","utf-8");
		//String ds="{\"keyWord\":\"" + address + "\"}";
		//ds=ds.replaceAll("\"", qt).replaceAll("\\{", le).replaceAll("\\}", ri);
		//list.add(new BasicNameValuePair("ds", ds));
		//list.add(new BasicNameValuePair("tk", "38fb44b582847ada168b0fa8fb587293"));
		String url="https://api.tianditu.gov.cn/geocoder?";
		String par="ds={\"keyWord\":\"延庆区北京市延庆区延庆镇莲花池村前街50夕阳红养老院\"}";
		par=par.replaceAll("\"", qt).replaceAll("\\{", le).replaceAll("\\}", ri);
		url+=par;
		url+="&&tk=38fb44b582847ada168b0fa8fb587293";
		//url=URLEncoder.encode(url,"gbk");
		String content = LonAndLatUtil.UrlConn(url, list);
		JSONObject jsStr = JSONObject.parseObject(content);
		String detail = jsStr.get("location") == null ? "" : jsStr.get("location").toString();
		System.out.println(detail);
		JSONObject detailJson = JSONObject.parseObject(detail);
		if (detailJson != null && !detailJson.equals("")) {
			System.out.println(detailJson.get("lon"));
			System.out.println(detailJson.get("lat"));
		}

	}

	@Override

	public void updateLonAndLat(String url,String mapKey) throws InterruptedException, ExecutionException {
		// TODO Auto-generated method stub
		if (url == null || "".equals(url)) {
			url = "http://api.tianditu.gov.cn/geocoder";
		}
		long aa=System.currentTimeMillis();
		List<Map> listOfEmptyAdd = creditMapDao.queryListOfEmptyAdd();
		List<Map> target =new ArrayList<Map>();
		long bb=System.currentTimeMillis();
		int poolSize=50;
		ExecutorService es = Executors.newFixedThreadPool(poolSize);
		List<Future<List<Map<String,String>>>> listFuture = new ArrayList<Future<List<Map<String,String>>>>();
		List<List<Map>> listE=averageAssign(listOfEmptyAdd, poolSize);
		for (int i = 0; i < poolSize; i++) {
			Callable c = new ThreadMapCallable(listE.get(i),url,mapKey);
			Future<List<Map<String,String>>> f = es.submit(c);
			listFuture.add(f);
		}
		es.shutdown();
		long b=System.currentTimeMillis();
		for (Future f : listFuture) {
			// 从Future对象上获取任务的返回值，并输出到控制台
			List<Map>  lm= (List<Map>) f.get();
			target.addAll(lm);
	    }
		long a=System.currentTimeMillis();
		//target.addAll((List<Map>)call(listOfEmptyAdd,url,mapKey));
		if(target!=null&&target.size()>0){
			creditMapDao.updateEmptyAddAll(target);
		}
	}
	
	public List<Map> call(List<Map> listE,String url,String mapKey) {
		if(StringUtils.isBlank(url)){
			url = "http://api.tianditu.gov.cn/geocoder";
		}
		if (listE != null && listE.size() > 0) {
			for (int i = 0; i < listE.size(); i++) {
				Map m = listE.get(i);
			    try{
				    String urlI=url;
					String address = m.get("zs").toString();
					List<NameValuePair> list = new ArrayList<NameValuePair>();
				/*	list.add(new BasicNameValuePair("ds", "{\"keyWord\":\"" + address + "\"}"));
					list.add(new BasicNameValuePair("tk", mapKey));*/
					String qt=URLEncoder.encode("\"","utf-8");
					String le=URLEncoder.encode("{","utf-8");
					String ri=URLEncoder.encode("}","utf-8");
					String par="?ds={\"keyWord\":\"" + address + "\"}";
					par=par.replaceAll("\"", qt).replaceAll("\\{", le).replaceAll("}", ri).replaceAll("#", "");
					urlI+=par;
					urlI+="&&tk="+mapKey;
					System.out.println(urlI);
					String content = LonAndLatUtil.UrlConn(urlI, list);
					if (content != null && !"".equals(content)) {
						System.out.println(content);
						/*JSONObject jsStr = JSONObject.parseObject(content);
						String detail = jsStr.get("location") == null ? "" : jsStr.get("location").toString();
						JSONObject detailJson = JSONObject.parseObject(detail);
						if (detailJson != null && !detailJson.equals("")) {
							creditMapDao.updateEmptyAdd(detailJson.get("lon").toString(), detailJson.get("lat").toString(),
									m.get("tybm").toString());
							listE.get(i).put("lon", detailJson.get("lon").toString());
							listE.get(i).put("lat", detailJson.get("lat").toString());
						}*/
					}

			  }catch(Exception e){
				  System.out.println(e.getMessage()+m.toString());
			  }
				
			}
		}
		return listE;
	}
	
	/**
	 * 将一组数据平均分成n组
	 *
	 * @param source
	 *            要分组的数据源
	 * @param n
	 *            平均分成n组
	 * @param <T>
	 * @return
	 */
	public static <T> List<List<T>> averageAssign(List<T> source, int n) {
		List<List<T>> result = new ArrayList<List<T>>();
		int remainder = source.size() % n; // (先计算出余数)
		int number = source.size() / n; // 然后是商
		int offset = 0;// 偏移量
		for (int i = 0; i < n; i++) {
			List<T> value = null;
			if (remainder > 0) {
				value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
				remainder--;
				offset++;
			} else {
				value = source.subList(i * number + offset, (i + 1) * number + offset);
			}
			result.add(value);
		}
		return result;
	}

	@Override
	public List<Map> queryListBasicMap(String type, String search, String sbnf, String qyid) {
		// TODO Auto-generated method stub
		return creditMapDao.queryListBasicMap(type, search, sbnf, qyid);
	}

	@Override
	public List<Map> queryMapAreaList(String qyid, String sbnf) {
		// TODO Auto-generated method stub
		return creditMapDao.queryMapAreaList(qyid, sbnf);
	}

	@Override
	public List<Map> queryMapDeptList(String qyid, String sbnf) {
		// TODO Auto-generated method stub
		return creditMapDao.queryMapDeptList(qyid, sbnf);
	}

	@Override
	public Map querySingleBasicInfBytybm(String tybm) {
		// TODO Auto-generated method stub
		return creditMapDao.querySingleBasicInfBytybm(tybm);
	}

	@Override
	public List<Map> queryAllAreaCodes() {
		// TODO Auto-generated method stub
		return creditMapDao.queryAllAreaCodes();
	}

	@Override
	@Transactional
	public void initAreaMap() {
		creditMapDao.deleteArea();
		Calendar date = Calendar.getInstance();
		String sbnf = String.valueOf((Integer) date.get(Calendar.YEAR));
		String nfAll = "0";
		String[] nfs = new String[] { sbnf, nfAll };
		for (int i = 0; i < nfs.length; i++) {
			// 企业基础信息
			creditMapDao.initMapAreaBasic(nfs[i]);

			// 法人行政许可
			creditMapDao.updateMapAreaBasic(nfs[i], "t_1000000010001_3ioj4GeZQU", "SBXZXKSL");
			// 自然人行政许可
			creditMapDao.updateMapAreaBasic(nfs[i], "t_1000010010003_vVwjDLoDWy", "SBXZXKSL");
			// 法人行政处罚
			creditMapDao.updateMapAreaBasic(nfs[i], "t_1000000010002_XSni4zSzP0", "SBXZCFSL");
			// 自然人行政处罚
			creditMapDao.updateMapAreaBasic(nfs[i], "t_1000010010004_KFPULZpF7D", "SBXZCFSL");
			// 法人红名单
			creditMapDao.updateMapAreaBasic(nfs[i], "t_1000000010005_JgddEske8s", "SBBMDSL");
			// 自然人红名单
			creditMapDao.updateMapAreaBasic(nfs[i], "t_1000010010006_5qTzTGI6gL", "SBBMDSL");
			// 法人黑名单
			creditMapDao.updateMapAreaBasic(nfs[i], "t_1000000010007_u6tnVOcB9I", "SBHMDSL");
			// 自然人黑名单
			creditMapDao.updateMapAreaBasic(nfs[i], "t_1000010010008_VU2pjsxdhk", "SBHMDSL");

			// 上报失信被执行人
			// creditMapDao.updateMapAreaLoseCredit(nfs[i], "SBSXBZXRSL");
			// 上报联合惩戒对象
			/// creditMapDao.updateMapAreaRewardAndPunish(nfs[i],"SBNHCJDXSL","c");
			// 上报联合激励对象
			// creditMapDao.updateMapAreaRewardAndPunish(nfs[i],"SBNHJLDXSL","j");
		}
		creditMapDao.initMapAreaBasicAddAll();
	}

	@Override
	@Transactional
	public void initDeptMap() {
		creditMapDao.deleteDept();
		Calendar date = Calendar.getInstance();
		String sbnf = String.valueOf((Integer) date.get(Calendar.YEAR));
		String nfAll = "0";
		String[] nfs = new String[] { sbnf, nfAll };
		for (int i = 0; i < nfs.length; i++) {
			// 企业基础信息
			creditMapDao.initMapDeptBasic(nfs[i]);

			// 法人行政许可
			creditMapDao.updateMapDeptBasic(nfs[i], "t_1000000010001_3ioj4GeZQU", "SBXZXKSL");
			// 自然人行政许可
			creditMapDao.updateMapDeptBasic(nfs[i], "t_1000010010003_vVwjDLoDWy", "SBXZXKSL");
			// 法人行政处罚
			creditMapDao.updateMapDeptBasic(nfs[i], "t_1000000010002_XSni4zSzP0", "SBXZCFSL");
			// 自然人行政处罚
			creditMapDao.updateMapDeptBasic(nfs[i], "t_1000010010004_KFPULZpF7D", "SBXZCFSL");
			// 法人红名单
			creditMapDao.updateMapDeptBasic(nfs[i], "t_1000000010005_JgddEske8s", "SBBMDSL");
			// 自然人红名单
			creditMapDao.updateMapDeptBasic(nfs[i], "t_1000010010006_5qTzTGI6gL", "SBBMDSL");
			// 法人黑名单
			creditMapDao.updateMapDeptBasic(nfs[i], "t_1000000010007_u6tnVOcB9I", "SBHMDSL");
			// 自然人黑名单
			creditMapDao.updateMapDeptBasic(nfs[i], "t_1000010010008_VU2pjsxdhk", "SBHMDSL");
			// 上报失信被执行人
			// creditMapDao.updateMapDeptLoseCredit(nfs[i], "SBSXBZXRSL");
			// 上报联合惩戒对象
			// creditMapDao.updateMapDeptRewardAndPunish(nfs[i],"SBNHCJDXSL","c");
			// 上报联合激励对象
			// creditMapDao.updateMapDeptRewardAndPunish(nfs[i],"SBNHJLDXSL","j");
		}
		creditMapDao.initMapDeptBasicAddAll();

	}

	@Override
	public List<Map<String, Object>> creditMapListByConditionForPage(List<String> columns, String[] additionalColumns,
			String conditionStr, Page page, String type, String search, String sbnf, String qyid) {
		List<String> conditions = SQLBuilder.createConditionSql(conditionStr);
		return creditMapDao.creditMapListByConditionForPage(columns, additionalColumns, conditions, page, type, search,
				sbnf, qyid);
	}

	@Override
	public Map getLonAndLatByQybm(String qybm) {
		// TODO Auto-generated method stub
		return creditMapDao.getLonAndLatByQybm(qybm);
	}

}
